using Microsoft.Extensions.Logging;
using Sage.Http.Authentication;
using Sage.Http.Configuration;
using Sage.Http.Core;
using Sage.Http.Models;
using Sage.Http.Utilities;
using System.Diagnostics.CodeAnalysis;
using System.Net.Http.Headers;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization.Metadata;

namespace Sage.Http.Extensions
{
    /// <summary>
    /// HTTP相关扩展方法的统一入口
    /// </summary>
    public static class HttpExtensions
    {
        #region HttpClient扩展方法

        /// <summary>
        /// 创建HTTP请求构建器，使用Core.HttpRequestBuilder实现
        /// </summary>
        /// <param name="client">HTTP客户端</param>
        /// <param name="method">HTTP方法</param>
        /// <param name="requestUri">请求URI</param>
        /// <returns>HTTP请求构建器</returns>
        /// <exception cref="ArgumentNullException">参数为null时抛出</exception>
        /// <remarks>
        /// 此方法返回一个流式API构建器，用于链式构建HTTP请求。
        /// </remarks>
        public static HttpRequestBuilder CreateRequest(
            this HttpClient client,
            HttpMethod method,
            string requestUri)
        {
            ArgumentNullException.ThrowIfNull(client);
            ArgumentNullException.ThrowIfNull(method);
            ArgumentException.ThrowIfNullOrEmpty(requestUri);

            // 创建临时的HttpRequestManager来包装HttpClient
            var manager = new HttpRequestManager(client, null, null, null, null, null);
            return new HttpRequestBuilder(manager, method, requestUri);
        }

        #endregion

        #region 认证扩展方法

        /// <summary>
        /// 为HttpClient设置默认认证提供者
        /// </summary>
        /// <param name="client">HTTP客户端</param>
        /// <param name="authProvider">认证提供者</param>
        /// <returns>配置了认证的HTTP客户端，用于链式调用</returns>
        public static HttpClient SetDefaultAuthentication(this HttpClient client, IAuthenticationProvider authProvider)
        {
            ArgumentNullException.ThrowIfNull(client);
            ArgumentNullException.ThrowIfNull(authProvider);

            // 保存认证提供者到客户端属性中
            SetAuthProviderProperty(client, "DefaultAuthProvider", authProvider);

            return client;
        }

        /// <summary>
        /// 为HttpClient设置Bearer Token认证
        /// </summary>
        /// <param name="client">HTTP客户端</param>
        /// <param name="token">认证令牌</param>
        /// <param name="scheme">认证方案，默认为"Bearer"</param>
        /// <returns>配置了认证的HTTP客户端，用于链式调用</returns>
        public static HttpClient SetBearerToken(this HttpClient client, string token, string scheme = "Bearer")
        {
            ArgumentNullException.ThrowIfNull(client);
            ArgumentException.ThrowIfNullOrEmpty(token);

            return SetDefaultAuthentication(client, new BearerTokenAuthProvider(token, scheme));
        }

        /// <summary>
        /// 为HttpClient设置Basic认证
        /// </summary>
        /// <param name="client">HTTP客户端</param>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <returns>配置了认证的HTTP客户端，用于链式调用</returns>
        public static HttpClient SetBasicAuth(this HttpClient client, string username, string password)
        {
            ArgumentNullException.ThrowIfNull(client);
            ArgumentException.ThrowIfNullOrEmpty(username);
            ArgumentException.ThrowIfNullOrEmpty(password);

            return SetDefaultAuthentication(client, new BasicAuthProvider(username, password));
        }

        /// <summary>
        /// 为HttpClient设置API Key认证
        /// </summary>
        /// <param name="client">HTTP客户端</param>
        /// <param name="apiKey">API密钥</param>
        /// <param name="parameterName">参数名称</param>
        /// <param name="location">密钥位置，头部或查询参数</param>
        /// <returns>配置了API Key的HTTP客户端，用于链式调用</returns>
        public static HttpClient SetApiKey(this HttpClient client, string apiKey, string parameterName, ApiKeyLocation location = ApiKeyLocation.Header)
        {
            ArgumentNullException.ThrowIfNull(client);
            ArgumentException.ThrowIfNullOrEmpty(apiKey);
            ArgumentException.ThrowIfNullOrEmpty(parameterName);

            return SetDefaultAuthentication(client, new ApiKeyAuthProvider(apiKey, parameterName, 
                location == ApiKeyLocation.QueryParameter ? parameterName : null));
        }

        /// <summary>
        /// 创建HTTP请求管理器
        /// </summary>
        /// <param name="client">HTTP客户端</param>
        /// <param name="logger">日志记录器</param>
        /// <returns>HTTP请求管理器</returns>
        public static HttpRequestManager CreateHttpRequestManager(this HttpClient client, ILogger? logger = null)
        {
            ArgumentNullException.ThrowIfNull(client);
            
            // 使用第一个构造函数，避免歧义
            return new HttpRequestManager(client, logger, null, null, null, null);
        }

        /// <summary>
        /// 设置客户端属性（AOT兼容版本 - 专用于IAuthenticationProvider）
        /// </summary>
        /// <param name="client">HTTP客户端</param>
        /// <param name="key">属性键</param>
        /// <param name="authProvider">认证提供者</param>
        /// <returns>HTTP客户端，用于链式调用</returns>
        public static HttpClient SetAuthProviderProperty(this HttpClient client, string key, IAuthenticationProvider authProvider)
        {
            ArgumentNullException.ThrowIfNull(client);
            ArgumentException.ThrowIfNullOrEmpty(key);
            ArgumentNullException.ThrowIfNull(authProvider);

            // 使用默认请求头存储自定义数据
            var propertyKey = $"X-Client-Property-{key}";
            client.DefaultRequestHeaders.Remove(propertyKey);
            
            // 存储认证提供者的类型名称，用于后续识别
            var authProviderType = authProvider.GetType().FullName;
            client.DefaultRequestHeaders.Add(propertyKey + "-Type", authProviderType);
            
            // 根据不同的认证提供者类型进行特殊处理
            if (authProvider is BearerTokenAuthProvider bearerAuth)
            {
                client.DefaultRequestHeaders.Add(propertyKey + "-Token", bearerAuth.Token);
                client.DefaultRequestHeaders.Add(propertyKey + "-Scheme", bearerAuth.Scheme);
            }
            else if (authProvider is BasicAuthProvider basicAuth)
            {
                client.DefaultRequestHeaders.Add(propertyKey + "-Username", basicAuth.Username);
                client.DefaultRequestHeaders.Add(propertyKey + "-Password", Convert.ToBase64String(Encoding.UTF8.GetBytes(basicAuth.Password)));
            }
            else if (authProvider is ApiKeyAuthProvider apiKeyAuth)
            {
                client.DefaultRequestHeaders.Add(propertyKey + "-ApiKey", apiKeyAuth.ApiKey);
                client.DefaultRequestHeaders.Add(propertyKey + "-Location", apiKeyAuth.Location.ToString());
                client.DefaultRequestHeaders.Add(propertyKey + "-Name", apiKeyAuth.Name);
            }
            // 对于自定义认证提供者，我们无法在AOT环境中序列化，但至少保留类型信息
            
            return client;
        }

        /// <summary>
        /// 获取认证提供者（AOT兼容版本）
        /// </summary>
        /// <param name="client">HTTP客户端</param>
        /// <param name="key">属性键</param>
        /// <returns>认证提供者，如果不存在则返回null</returns>
        public static IAuthenticationProvider? GetAuthProviderProperty(this HttpClient client, string key)
        {
            ArgumentNullException.ThrowIfNull(client);
            ArgumentException.ThrowIfNullOrEmpty(key);

            var propertyKey = $"X-Client-Property-{key}";
            
            // 检查类型信息
            if (!client.DefaultRequestHeaders.TryGetValues(propertyKey + "-Type", out var typeValues))
            {
                return null;
            }
            
            var typeName = typeValues.FirstOrDefault();
            if (string.IsNullOrEmpty(typeName))
            {
                return null;
            }
            
            // 根据类型创建相应的认证提供者
            if (typeName.Contains("BearerTokenAuthProvider"))
            {
                if (client.DefaultRequestHeaders.TryGetValues(propertyKey + "-Token", out var tokenValues) &&
                    client.DefaultRequestHeaders.TryGetValues(propertyKey + "-Scheme", out var schemeValues))
                {
                    var token = tokenValues.FirstOrDefault();
                    var scheme = schemeValues.FirstOrDefault() ?? "Bearer";
                    if (!string.IsNullOrEmpty(token))
                    {
                        return new BearerTokenAuthProvider(token, scheme);
                    }
                }
            }
            else if (typeName.Contains("BasicAuthProvider"))
            {
                if (client.DefaultRequestHeaders.TryGetValues(propertyKey + "-Username", out var usernameValues) &&
                    client.DefaultRequestHeaders.TryGetValues(propertyKey + "-Password", out var passwordValues))
                {
                    var username = usernameValues.FirstOrDefault();
                    var passwordBase64 = passwordValues.FirstOrDefault();
                    if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(passwordBase64))
                    {
                        try
                        {
                            var passwordBytes = Convert.FromBase64String(passwordBase64);
                            var password = Encoding.UTF8.GetString(passwordBytes);
                            return new BasicAuthProvider(username, password);
                        }
                        catch
                        {
                            // 忽略解码错误
                        }
                    }
                }
            }
            else if (typeName.Contains("ApiKeyAuthProvider"))
            {
                if (client.DefaultRequestHeaders.TryGetValues(propertyKey + "-ApiKey", out var apiKeyValues) &&
                    client.DefaultRequestHeaders.TryGetValues(propertyKey + "-Name", out var nameValues))
                {
                    var apiKey = apiKeyValues.FirstOrDefault();
                    var name = nameValues.FirstOrDefault();
                    if (!string.IsNullOrEmpty(apiKey) && !string.IsNullOrEmpty(name))
                    {
                        if (client.DefaultRequestHeaders.TryGetValues(propertyKey + "-Location", out var locationValues))
                        {
                            var locationStr = locationValues.FirstOrDefault();
                            if (locationStr == ApiKeyLocation.QueryParameter.ToString())
                            {
                                return new ApiKeyAuthProvider(apiKey, "X-API-Key", name);
                            }
                        }
                        return new ApiKeyAuthProvider(apiKey, name);
                    }
                }
            }
            
            // 对于自定义认证提供者，我们无法在AOT环境中反序列化
            return null;
        }

        /// <summary>
        /// 获取客户端属性
        /// </summary>
        /// <typeparam name="T">属性类型</typeparam>
        /// <param name="client">HTTP客户端</param>
        /// <param name="key">属性键</param>
        /// <param name="jsonTypeInfo">JSON类型信息，用于AOT环境</param>
        /// <param name="defaultValue">默认值</param>
        /// <returns>属性值，如果不存在则返回默认值</returns>
        [RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
        [RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
        [Obsolete("此方法在不提供JsonTypeInfo参数时在AOT环境中不安全")]
        public static T? GetClientProperty<T>(this HttpClient client, string key, JsonTypeInfo<T>? jsonTypeInfo = null, T? defaultValue = default)
        {
            ArgumentNullException.ThrowIfNull(client);
            ArgumentException.ThrowIfNullOrEmpty(key);

            var propertyKey = $"X-Client-Property-{key}";
            if (client.DefaultRequestHeaders.TryGetValues(propertyKey, out var values))
            {
                var value = values.FirstOrDefault();
                if (value != null)
                {
                    try
                    {
                        var bytes = Convert.FromBase64String(value);
                        var json = Encoding.UTF8.GetString(bytes);
                        
                        if (jsonTypeInfo != null)
                        {
                            return JsonSerializer.Deserialize(json, jsonTypeInfo);
                        }
                        else
                        {
                            return JsonSerializer.Deserialize<T>(json);
                        }
                    }
                    catch
                    {
                        // 忽略反序列化错误
                    }
                }
            }

            return defaultValue;
        }

        #endregion

        #region 下载扩展方法

        /// <summary>
        /// 下载文件并报告进度
        /// </summary>
        /// <param name="client">HTTP客户端</param>
        /// <param name="requestUri">请求URI</param>
        /// <param name="destinationPath">目标文件路径</param>
        /// <param name="progress">进度报告接口</param>
        /// <param name="bufferSize">缓冲区大小，默认81920字节(80KB)</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>下载的总字节数</returns>
        /// <exception cref="ArgumentNullException">参数为null时</exception>
        /// <exception cref="HttpRequestException">HTTP请求失败时</exception>
        /// <exception cref="IOException">文件I/O错误时</exception>
        public static async Task<long> DownloadFileAsync(
            this HttpClient client,
            string requestUri,
            string destinationPath,
            IProgress<float>? progress = null,
            int bufferSize = 81920,
            CancellationToken cancellationToken = default)
        {
            ArgumentNullException.ThrowIfNull(client);
            ArgumentException.ThrowIfNullOrEmpty(requestUri);
            ArgumentException.ThrowIfNullOrEmpty(destinationPath);

            // 确保目标目录存在
            var directory = Path.GetDirectoryName(destinationPath);
            if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            // 使用FileMode.Create以确保文件被创建或覆盖
            using var fileStream = new FileStream(
                destinationPath,
                FileMode.Create,
                FileAccess.Write,
                FileShare.None,
                bufferSize,
                useAsync: true);

            return await DownloadToStreamAsync(
                client,
                requestUri,
                fileStream,
                progress,
                bufferSize,
                cancellationToken).ConfigureAwait(false);
        }

        /// <summary>
        /// 下载内容到流并报告进度
        /// </summary>
        /// <param name="client">HTTP客户端</param>
        /// <param name="requestUri">请求URI</param>
        /// <param name="destination">目标流</param>
        /// <param name="progress">进度报告接口</param>
        /// <param name="bufferSize">缓冲区大小，默认81920字节(80KB)</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>下载的总字节数</returns>
        /// <exception cref="ArgumentNullException">参数为null时</exception>
        /// <exception cref="ArgumentException">目标流不可写时</exception>
        /// <exception cref="HttpRequestException">HTTP请求失败时</exception>
        public static async Task<long> DownloadToStreamAsync(
            this HttpClient client,
            string requestUri,
            Stream destination,
            IProgress<float>? progress = null,
            int bufferSize = 81920,
            CancellationToken cancellationToken = default)
        {
            ArgumentNullException.ThrowIfNull(client);
            ArgumentException.ThrowIfNullOrEmpty(requestUri);
            ArgumentNullException.ThrowIfNull(destination);

            if (!destination.CanWrite)
                throw new ArgumentException("目标流必须可写", nameof(destination));

            // 使用ResponseHeadersRead选项，以便在接收到头信息后就返回响应
            using var response = await client.GetAsync(
                requestUri,
                HttpCompletionOption.ResponseHeadersRead,
                cancellationToken).ConfigureAwait(false);

            response.EnsureSuccessStatusCode();

            var contentLength = response.Content.Headers.ContentLength;
            using var contentStream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);

            // 如果没有内容长度信息，无法报告准确进度
            if (contentLength.HasValue && progress != null)
            {
                return await CopyToWithProgressAsync(
                    contentStream,
                    destination,
                    contentLength.Value,
                    progress,
                    bufferSize,
                    cancellationToken).ConfigureAwait(false);
            }
            else
            {
                // 没有进度报告的简单复制
                await contentStream.CopyToAsync(destination, bufferSize, cancellationToken).ConfigureAwait(false);
                return destination.Position;
            }
        }

        /// <summary>
        /// 带进度报告的流复制
        /// </summary>
        /// <param name="source">源流</param>
        /// <param name="destination">目标流</param>
        /// <param name="totalBytes">总字节数</param>
        /// <param name="progress">进度报告接口</param>
        /// <param name="bufferSize">缓冲区大小</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>复制的总字节数</returns>
        private static async Task<long> CopyToWithProgressAsync(
            Stream source,
            Stream destination,
            long totalBytes,
            IProgress<float> progress,
            int bufferSize,
            CancellationToken cancellationToken)
        {
            var buffer = new byte[bufferSize];
            long totalBytesRead = 0;
            int bytesRead;

            while ((bytesRead = await source.ReadAsync(buffer, cancellationToken).ConfigureAwait(false)) > 0)
            {
                await destination.WriteAsync(buffer.AsMemory(0, bytesRead), cancellationToken).ConfigureAwait(false);
                totalBytesRead += bytesRead;

                // 报告进度
                var progressPercentage = (float)totalBytesRead / totalBytes;
                progress.Report(progressPercentage);
            }

            return totalBytesRead;
        }

        #endregion

        #region 流式处理扩展方法

        /// <summary>
        /// 获取流式响应并逐行处理JSON数据
        /// </summary>
        /// <typeparam name="T">响应项类型</typeparam>
        /// <param name="client">HTTP客户端</param>
        /// <param name="requestUri">请求URI</param>
        /// <param name="deserializer">自定义反序列化函数，如果为null则自动创建</param>
        /// <param name="jsonTypeInfo">JSON类型信息，用于AOT环境（推荐）</param>
        /// <param name="jsonOptions">自定义JSON序列化选项</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>响应项的异步枚举器</returns>
        /// <remarks>
        /// 此方法适用于Server-Sent Events (SSE)或其他流式JSON响应。
        /// 每行应包含一个完整的JSON对象。
        /// 
        /// 在AOT环境中，建议提供jsonTypeInfo参数以启用源生成序列化。
        /// </remarks>
        [RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
        [RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation.")]
        public static async IAsyncEnumerable<T> GetStreamingAsync<T>(
            this HttpClient client,
            string requestUri,
            Func<string, T>? deserializer = null,
            JsonTypeInfo<T>? jsonTypeInfo = null,
            JsonSerializerOptions? jsonOptions = null,
            [EnumeratorCancellation] CancellationToken cancellationToken = default)
        {
            ArgumentNullException.ThrowIfNull(client);
            ArgumentException.ThrowIfNullOrEmpty(requestUri);

            HttpResponseMessage? response = null;
            Stream? stream = null;
            StreamReader? reader = null;

            try
            {
                var request = new HttpRequestMessage(HttpMethod.Get, requestUri);

                // 添加适合流式响应的头
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/event-stream"));

                // 使用ResponseHeadersRead选项，以便在接收到头信息后就返回响应
                response = await client.SendAsync(
                    request,
                    HttpCompletionOption.ResponseHeadersRead,
                    cancellationToken).ConfigureAwait(false);

                response.EnsureSuccessStatusCode();

                // 创建反序列化函数
                deserializer ??= JsonSerializerUtilities.CreateDeserializer(jsonTypeInfo, jsonOptions);

                stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
                reader = new StreamReader(stream);

                string? line;
                while ((line = await reader.ReadLineAsync(cancellationToken).ConfigureAwait(false)) != null)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    // 跳过空行
                    if (string.IsNullOrWhiteSpace(line))
                        continue;

                    // 提取并处理数据行
                    string dataContent = ExtractDataContent(line);
                    if (string.IsNullOrEmpty(dataContent))
                        continue;

                    // 处理数据行
                    if (JsonSerializerUtilities.TryDeserialize(dataContent, deserializer, out T? item) &&
                        item is not null)
                    {
                        yield return item;
                    }
                }
            }
            finally
            {
                // 按照创建的相反顺序释放资源
                // 优先使用异步释放（如果支持）
                if (reader is IAsyncDisposable asyncReader)
                    await asyncReader.DisposeAsync().ConfigureAwait(false);
                else
                    reader?.Dispose();

                if (stream is IAsyncDisposable asyncStream)
                    await asyncStream.DisposeAsync().ConfigureAwait(false);
                else
                    stream?.Dispose();

                if (response is IAsyncDisposable asyncResponse)
                    await asyncResponse.DisposeAsync().ConfigureAwait(false);
                else
                    response?.Dispose();
            }
        }

        /// <summary>
        /// 处理流式响应并通过回调函数处理每一行
        /// </summary>
        /// <param name="client">HTTP客户端</param>
        /// <param name="requestUri">请求URI</param>
        /// <param name="lineProcessor">行处理回调函数</param>
        /// <param name="isEventStream">是否为Server-Sent Events流</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>处理的总行数</returns>
        public static async Task<int> ProcessStreamAsync(
            this HttpClient client,
            string requestUri,
            Func<string, Task> lineProcessor,
            bool isEventStream = false,
            CancellationToken cancellationToken = default)
        {
            ArgumentNullException.ThrowIfNull(client);
            ArgumentException.ThrowIfNullOrEmpty(requestUri);
            ArgumentNullException.ThrowIfNull(lineProcessor);

            var request = new HttpRequestMessage(HttpMethod.Get, requestUri);

            // 添加适合流式响应的头
            if (isEventStream)
            {
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/event-stream"));
            }

            // 使用ResponseHeadersRead选项，以便在接收到头信息后就返回响应
            using var response = await client.SendAsync(
                request,
                HttpCompletionOption.ResponseHeadersRead,
                cancellationToken).ConfigureAwait(false);

            response.EnsureSuccessStatusCode();

            using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
            using var reader = new StreamReader(stream);

            int lineCount = 0;
            string? line;
            while ((line = await reader.ReadLineAsync(cancellationToken).ConfigureAwait(false)) != null)
            {
                cancellationToken.ThrowIfCancellationRequested();

                // 跳过空行
                if (string.IsNullOrWhiteSpace(line))
                    continue;

                // 处理数据行
                string dataContent;
                if (isEventStream && line.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
                {
                    dataContent = line[5..].Trim();
                    if (string.IsNullOrEmpty(dataContent))
                        continue;
                }
                else
                {
                    dataContent = line;
                }

                await lineProcessor(dataContent).ConfigureAwait(false);
                lineCount++;
            }

            return lineCount;
        }

        /// <summary>
        /// 发送POST请求并获取流式响应
        /// </summary>
        /// <typeparam name="T">响应项类型</typeparam>
        /// <param name="client">HTTP客户端</param>
        /// <param name="requestUri">请求URI</param>
        /// <param name="content">请求内容</param>
        /// <param name="deserializer">自定义反序列化函数，如果为null则自动创建</param>
        /// <param name="jsonTypeInfo">JSON类型信息，用于AOT环境（推荐）</param>
        /// <param name="jsonOptions">自定义JSON序列化选项</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>响应项的异步枚举器</returns>
        /// <remarks>
        /// 此方法特别适用于需要发送请求体的流式API，如ChatGPT等AI模型的流式响应。
        /// 
        /// 在AOT环境中，建议提供jsonTypeInfo参数以启用源生成序列化。
        /// </remarks>
        [RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
        [RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation.")]
        public static async IAsyncEnumerable<T> PostStreamingAsync<T>(
            this HttpClient client,
            string requestUri,
            HttpContent content,
            Func<string, T>? deserializer = null,
            JsonTypeInfo<T>? jsonTypeInfo = null,
            JsonSerializerOptions? jsonOptions = null,
            [EnumeratorCancellation] CancellationToken cancellationToken = default)
        {
            ArgumentNullException.ThrowIfNull(client);
            ArgumentException.ThrowIfNullOrEmpty(requestUri);
            ArgumentNullException.ThrowIfNull(content);

            HttpResponseMessage? response = null;
            Stream? stream = null;
            StreamReader? reader = null;

            try
            {
                var request = new HttpRequestMessage(HttpMethod.Post, requestUri)
                {
                    Content = content
                };

                // 添加适合流式响应的头
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/event-stream"));

                // 使用ResponseHeadersRead选项，以便在接收到头信息后就返回响应
                response = await client.SendAsync(
                    request,
                    HttpCompletionOption.ResponseHeadersRead,
                    cancellationToken).ConfigureAwait(false);

                response.EnsureSuccessStatusCode();

                // 创建反序列化函数
                deserializer ??= JsonSerializerUtilities.CreateDeserializer(jsonTypeInfo, jsonOptions);

                stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
                reader = new StreamReader(stream);

                string? line;
                while ((line = await reader.ReadLineAsync(cancellationToken).ConfigureAwait(false)) != null)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    // 跳过空行
                    if (string.IsNullOrWhiteSpace(line))
                        continue;

                    // 提取并处理数据行
                    string dataContent = ExtractDataContent(line);
                    if (string.IsNullOrEmpty(dataContent))
                        continue;

                    // 处理数据行
                    if (JsonSerializerUtilities.TryDeserialize(dataContent, deserializer, out T? item) &&
                        item is not null)
                    {
                        yield return item;
                    }
                }
            }
            finally
            {
                reader?.Dispose();
                stream?.Dispose();
                response?.Dispose();
            }
        }

        /// <summary>
        /// 提取数据内容，处理SSE格式和普通文本行
        /// </summary>
        /// <param name="line">原始行文本</param>
        /// <returns>数据内容</returns>
        private static string ExtractDataContent(string line)
        {
            // 检查是否为SSE格式的数据行
            if (line.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
            {
                return line[5..].Trim();
            }

            return line;
        }

        #endregion

        #region HttpRequestBuilder扩展方法

        /// <summary>
        /// 添加Bearer Token认证
        /// </summary>
        /// <param name="builder">HTTP请求构建器</param>
        /// <param name="token">认证令牌</param>
        /// <param name="scheme">认证方案，默认为"Bearer"</param>
        /// <returns>当前构建器实例，用于链式调用</returns>
        public static Core.HttpRequestBuilder WithBearerToken(this Core.HttpRequestBuilder builder, string token, string scheme = "Bearer")
        {
            ArgumentNullException.ThrowIfNull(builder);
            ArgumentException.ThrowIfNullOrEmpty(token);

            return builder.WithAuthentication(new BearerTokenAuthProvider(token, scheme));
        }

        /// <summary>
        /// 添加Basic认证
        /// </summary>
        /// <param name="builder">HTTP请求构建器</param>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <returns>当前构建器实例，用于链式调用</returns>
        public static Core.HttpRequestBuilder WithBasicAuth(this Core.HttpRequestBuilder builder, string username, string password)
        {
            ArgumentNullException.ThrowIfNull(builder);
            ArgumentException.ThrowIfNullOrEmpty(username);
            ArgumentException.ThrowIfNullOrEmpty(password);

            return builder.WithAuthentication(new BasicAuthProvider(username, password));
        }

        /// <summary>
        /// 添加API Key认证
        /// </summary>
        /// <param name="builder">HTTP请求构建器</param>
        /// <param name="apiKey">API密钥</param>
        /// <param name="parameterName">参数名称</param>
        /// <param name="location">认证位置</param>
        /// <returns>当前构建器实例，用于链式调用</returns>
        public static Core.HttpRequestBuilder WithApiKey(this Core.HttpRequestBuilder builder, string apiKey, string parameterName, ApiKeyLocation location = ApiKeyLocation.Header)
        {
            ArgumentNullException.ThrowIfNull(builder);
            ArgumentException.ThrowIfNullOrEmpty(apiKey);
            ArgumentException.ThrowIfNullOrEmpty(parameterName);

            // 根据位置类型决定如何传递参数
            return location switch
            {
                ApiKeyLocation.Header => builder.WithAuthentication(new ApiKeyAuthProvider(apiKey, parameterName, null)),
                ApiKeyLocation.QueryParameter => builder.WithAuthentication(new ApiKeyAuthProvider(apiKey, "X-API-Key", parameterName)),
                _ => throw new ArgumentException($"不支持的 API 密钥位置: {location}", nameof(location))
            };
        }

        #endregion

        #region HttpResponseMessage扩展方法

        /// <summary>
        /// 获取响应头中的Location值
        /// </summary>
        public static string? GetLocationHeader(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);
            return response.Headers.Location?.ToString();
        }

        /// <summary>
        /// 获取内容类型
        /// </summary>
        public static string? GetContentType(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);
            return response.Content?.Headers.ContentType?.MediaType;
        }

        /// <summary>
        /// 获取内容长度
        /// </summary>
        public static long? GetContentLength(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);
            return response.Content?.Headers.ContentLength;
        }

        /// <summary>
        /// 获取ETag值（用于缓存验证）
        /// </summary>
        public static string? GetETag(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);
            return response.Headers.ETag?.Tag;
        }

        /// <summary>
        /// 获取最后修改时间
        /// </summary>
        public static DateTimeOffset? GetLastModified(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);
            return response.Content?.Headers.LastModified;
        }

        /// <summary>
        /// 获取API速率限制信息
        /// </summary>
        /// <param name="response">HTTP响应消息</param>
        /// <returns>速率限制信息</returns>
        public static RateLimitInfo GetRateLimitInfo(this HttpResponseMessage response)
        {
            var info = new RateLimitInfo();

            // 使用 Span<T> 优化字符串操作
            if (response.Headers.TryGetValues("X-RateLimit-Limit", out var limitValues))
            {
                var limitValue = limitValues.FirstOrDefault();
                if (!string.IsNullOrEmpty(limitValue) && int.TryParse(limitValue.AsSpan(), out var limit))
                {
                    info.Limit = limit;
                }
            }

            if (response.Headers.TryGetValues("X-RateLimit-Remaining", out var remainingValues))
            {
                var remainingValue = remainingValues.FirstOrDefault();
                if (!string.IsNullOrEmpty(remainingValue) && int.TryParse(remainingValue.AsSpan(), out var remaining))
                {
                    info.Remaining = remaining;
                }
            }

            if (response.Headers.TryGetValues("X-RateLimit-Reset", out var resetValues))
            {
                var resetValue = resetValues.FirstOrDefault();
                if (!string.IsNullOrEmpty(resetValue) && long.TryParse(resetValue.AsSpan(), out var resetTimestamp))
                {
                    info.ResetTime = DateTimeOffset.FromUnixTimeSeconds(resetTimestamp);
                }
            }

            return info;
        }

        /// <summary>
        /// 获取重试等待时间（秒）
        /// </summary>
        public static int? GetRetryAfterSeconds(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);

            if (response.Headers.RetryAfter == null)
                return null;

            if (response.Headers.RetryAfter.Delta.HasValue)
                return (int)response.Headers.RetryAfter.Delta.Value.TotalSeconds;

            if (response.Headers.RetryAfter.Date.HasValue)
            {
                var timeToWait = response.Headers.RetryAfter.Date.Value - DateTimeOffset.UtcNow;
                return (int)Math.Max(0, timeToWait.TotalSeconds);
            }

            return null;
        }

        /// <summary>
        /// 尝试获取指定的响应头值
        /// </summary>
        public static string? GetHeaderValue(this HttpResponseMessage response, string headerName)
        {
            ArgumentNullException.ThrowIfNull(response);
            ArgumentException.ThrowIfNullOrEmpty(headerName);

            if (response.Headers.TryGetValues(headerName, out IEnumerable<string>? values) && values != null)
            {
                return values.FirstOrDefault();
            }

            // 有些头部可能在Content.Headers中
            if (response.Content?.Headers.TryGetValues(headerName, out values) == true && values != null)
            {
                return values.FirstOrDefault();
            }

            return null;
        }

        /// <summary>
        /// 获取所有响应头
        /// </summary>
        public static Dictionary<string, string> GetAllHeaders(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);

            var headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

            // 添加响应头
            foreach (var header in response.Headers)
            {
                headers[header.Key] = string.Join(", ", header.Value);
            }

            // 添加内容头
            if (response.Content != null)
            {
                foreach (var header in response.Content.Headers)
                {
                    headers[header.Key] = string.Join(", ", header.Value);
                }
            }

            return headers;
        }

        #endregion
    }
}